package com.stenio.fancat.controller.shop;

import com.baomidou.mybatisplus.plugins.Page;
import com.stenio.fancat.controller.Result;
import com.stenio.fancat.domain.shop.*;
import com.stenio.fancat.domain.user.UserRelationship;
import com.stenio.fancat.exception.FanCatException;
import com.stenio.fancat.form.shop.ShopOrderForm;
import com.stenio.fancat.mapper.shop.FcOrderMapper;
import com.stenio.fancat.mapper.user.UserRelationshipMapper;
import com.stenio.fancat.service.baby.BabyPartnerService;
import com.stenio.fancat.service.behavior.BehaviorLogService;
import com.stenio.fancat.service.enums.OrderStatus;
import com.stenio.fancat.service.enums.OrderType;
import com.stenio.fancat.service.shop.*;
import com.stenio.fancat.util.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zhangqiu
 * @date 2018/12/1
 * @desc
 **/
@RestController
@RequestMapping("order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private VenderService venderService;

    @Autowired
    private ShopService shopService;

    @Autowired
    private ShopFleaService shopFleaService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private BehaviorLogService behaviorLogService;

    @Autowired
    private FcOrderMapper fcOrderMapper;

    @Autowired
    private UserRelationshipMapper userRelationshipMapper;

    @Value("${key}")
    private String key;

    @PostMapping("add")
    @ResponseBody
    public Result<FcOrder> add(@RequestBody ShopOrderForm shopForm){
        Result<FcOrder> result = new Result();
        FcOrder order = null;
        try {
            order = orderService.saveOrder(shopForm);
            String babyId = behaviorLogService.selectBabyId(shopForm.getUserId());
            redisUtil.del(key+babyId);
            FcShop fcshop = shopService.getById(shopForm.getBusinessId());
            redisUtil.del("shopGoods" + fcshop.getCategoryId(),"shopGoodsSingle"+fcshop.getId());
        } catch (FanCatException e) {
            result.setFlag(Result.FLAG.failure);
            result.setMsg(e.getMessage());
            return result;
        }
        result.setData(order);
        return result;
    }

    @PostMapping("update")
    @ResponseBody
    public Result update(@RequestBody ShopOrderForm orderForm) throws FanCatException {
        Result<FcOrder> result = new Result();
        if(orderForm.getOrderStatus()!=null&&orderForm.getOrderStatus()==OrderStatus.SEND.getStatus()){
            orderForm.setSendTime(new Date());
        }
        FcOrder fcOrder = fcOrderMapper.selectById(orderForm.getId());
        String babyId = behaviorLogService.selectBabyId(fcOrder.getUserId());
        try {
            babyId = behaviorLogService.selectBabyId(fcOrder.getUserId());
        } catch (FanCatException e) {
            result.setFlag(Result.FLAG.failure);
            result.setMsg(e.getMessage());
            return result;
        }
        redisUtil.del(key+babyId);
        redisUtil.del("UOrderInfo"+orderForm.getId());
        result.setData(orderService.updateOrder(orderForm));
        return result;
    }

    @GetMapping("get/{id}")
    @ResponseBody
    public Result get(@PathVariable Integer id){
        String key = "UOrderInfo"+id;
        Object redisData = redisUtil.get(key);
        Result<OrderVo> result = new Result();
        if(redisData == null) {
            FcOrder order = orderService.getById(id);
            if(order == null) {
                result.setFlag(Result.FLAG.failure);
                return result;
            }
            OrderVo orderVo = orderToVo(order);
            redisUtil.set(key,orderVo);
            result.setData(orderVo);
        }else {
            result.setData((OrderVo)redisData);
        }
        return result;
    }

    /**
     * 通过用户id和订单类型查询订单列表
     * @param id
     * @param status
     * @return
     */
    @PostMapping("getByOrderType/{id}/{status}")
    @ResponseBody
    public Result getByOrderType(@PathVariable String id, @PathVariable Integer status){
        Result result = new Result();
        List<FcOrder> fcOrders = orderService.getByOrderType(id,status);
        Map<String,List<OrderVo>> orderVos = new HashMap<>();
        SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日");
        if(CollectionUtils.isNotEmpty(fcOrders)) {
            for(FcOrder fcOrder : fcOrders) {
                String format = s.format(fcOrder.getCreateTime());
                if(orderVos.containsKey(format)) {
                    orderVos.get(format).add(orderToVo(fcOrder));
                }else {
                    List<OrderVo> newList = new ArrayList<>();
                    newList.add(orderToVo(fcOrder));
                    orderVos.put(format,newList);
                }
            }
        }else {
            result.setFlag(Result.FLAG.failure);
            return result;
        }
        List orderList = new ArrayList();
        for(Map.Entry entry : orderVos.entrySet()) {
            Map newMap = new HashMap();
            newMap.put("dateTime",entry.getKey());
            newMap.put("order",entry.getValue());
            orderList.add(newMap);
        }
        result.setData(orderList);
        return result;
    }

    /**
     * 通过用户id和订单类型查询订单列表
     * @param id
     * @param status
     * @return
     */
    @PostMapping("getByOrderType1/{id}/{status}")
    @ResponseBody
    public Result getByOrderType1(@PathVariable String id, @PathVariable Integer status){
        Result result = new Result();
        List<FcOrder> fcOrders = orderService.getByOrderType(id,status);
        List<Map<String,List>> a = new ArrayList();
        SimpleDateFormat s = new SimpleDateFormat("yyyy年MM月dd日");
        Map<String,List> map = new HashMap();
        List orderList = new ArrayList();
        if(CollectionUtils.isNotEmpty(fcOrders)) {
            for(int i=1;i<fcOrders.size();i++) {
                orderList.add(fcOrders.get(0));
                map.put("order",orderList);
                String format = s.format(fcOrders.get(i-1).getCreateTime());
                String format2 = s.format(fcOrders.get(i).getCreateTime());
                if(format.equals(format2)) {
                    ((List)(map.get("order"))).add(orderToVo(fcOrders.get(i)));
                }else {
                    List newList = new ArrayList();
                    newList.add(fcOrders.get(i));
                    Map newMap = new HashMap();
                    newMap.put("order",newList);
                    //a.add(i,map);
                    a.add(newMap);
                }
            }
            a.add(map);
        }else {
            result.setFlag(Result.FLAG.failure);
            return result;
        }
        result.setData(a);
        return result;
    }


    @PostMapping("page")
    @ResponseBody
    public Result page(@RequestBody ShopOrderForm orderForm){
        Result<Map<String,Object>> result = new Result();
        Page<FcOrder> page = orderService.selectByPage(orderForm);
        Map<String,Object> data = new HashMap<>();
        if(page!=null){
            data.put("current",page.getCurrent());
            data.put("pages",page.getPages());
            data.put("size",page.getSize());
            data.put("total",page.getTotal());
            List<OrderVo> records = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(page.getRecords())){
                page.getRecords().stream().forEach(shop->{
                    records.add(orderToVo(shop));
                });
            }
            data.put("records",records);
        }
        result.setData(data);
        return result;
    }

    private OrderVo orderToVo(FcOrder fcOrder){
        OrderVo vo = new OrderVo();
        BeanUtils.copyProperties(fcOrder,vo);
        UserRelationship userRelationship = userRelationshipMapper.selectUserInfoById(fcOrder.getUserId());
        if(userRelationship != null) {
            vo.setUserName(userRelationship.getName());//TODO
        }
        if(OrderType.getEnumByStatus(fcOrder.getOrderType())==OrderType.WARE){
            FcShop fcShop = shopService.getById(fcOrder.getBusinessId());
            FcVender fcVender = venderService.findById(fcShop.getVenderId());
            vo.setWareType(getWareTypeByCatId(fcShop.getCategoryId()));
            vo.setWareName(fcShop.getName());
            vo.setVenderName(fcVender.getName());
            vo.setVenderId(fcVender.getId());
        } else if(OrderType.getEnumByStatus(fcOrder.getOrderType())==OrderType.LOTERRY){
            FcShop fcShop = shopService.getById(fcOrder.getBusinessId());
            FcVender fcVender = venderService.findById(fcShop.getVenderId());
            vo.setWareType(getWareTypeByCatId(fcShop.getCategoryId()));
            vo.setWareName(fcShop.getName());
            vo.setVenderName(fcVender.getName());
            vo.setVenderId(fcVender.getId());
        } else if(OrderType.getEnumByStatus(fcOrder.getOrderType())==OrderType.REDPACK){
            vo.setTaskName("none....");//TOOD
        } else if(OrderType.getEnumByStatus(fcOrder.getOrderType())==OrderType.WAREFLEA){
            FcShopFlea fcShop = shopFleaService.getById(fcOrder.getBusinessId());
            FcVender fcVender = venderService.findById(fcShop.getVenderId());
            vo.setWareType(getWareTypeByCatId(fcShop.getCategoryId()));
            vo.setWareName(fcShop.getName());
            vo.setVenderName(fcVender.getName());
            vo.setVenderId(fcVender.getId());
        }
        return vo;
    }

    private Integer getWareTypeByCatId(Integer categoryId){
        FcCategory cat2 =  categoryService.findById(categoryId);
        FcCategory cat1 =  categoryService.findById(cat2.getParentId());
        if(cat1.getName().contains("实体")){
            return 1;
        } else{
            return 2;
        }
    }

}
